/***************************************************************************
 *   Copyright (C) 2005 by xihe   *
 *   xihels@163.com                                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef _RECEIVE_IM_BODY_H_
#define _RECEIVE_IM_BODY_H_

#include "ReceiveIMHeader.h"


/**
 * 消息中可能内嵌一些图片信息，除了普通的文本之外，图片的信息格式为：
 * 一. 缺省表情，缺省表情的前导字节是0x14，0x14之后的一个字节表示缺省表情的索引值
 * 二. 自定义表情，自定义表情的前导字节是0x15，0x15之后的格式为:
 * 	  1. 存在性字节，如果这个表情第一次出现，则为0x33，
 * 	  如果已经出现过，则为0x34，当为0x33时，后面的内容是
 * 		 i.   扩展名长度字节，从'0'为基准，
 * 		 如果表情图片的扩展名是gif，在这个值是'2' (有待证实)
 *       ii.  表情图片的文件名，其文件名由md5的字符串形式和扩展名构成，
 *       因此这个长度应该是32 + 1 + 扩展名长度
 *       iii. 表情的shortcut长度，以'A'为基准，如果长度是2，则这个字节是'C'
 *       iv.  表情的shortcut
 *    2. 如果为0x34时，则后面的内容为：
 * 		 i.   1字节索引值，假如这个自定义表情出现在第一个位置，则这个字节为'A'   
 *    3. 如果为0x36时
 * 		 i. 0x20
 *       ii. 一个未知字节，可能为0x38，可能为0x39，为0x38时，
 *       后面还有82字节，为0x39时，后面还有88字节  
 *    4. 如果为0x37时，则后面的内容还未知，长度是6字节
 * 
 */
int filterMsg(string& msg, const uint8_t* buf, int len); // 过滤器

/**
 * 普通消息的本体，其在NormalIMHeader之后
 */ 
class NormalIMBody {
    public:
	NormalIMBody();
	~NormalIMBody();
	int getBody(const uint8_t* buf, int len);
	const string& getMessage() const    { return message; }
	uint32_t hasFontAttr() const	    { return hasFontAttribute; }
	uint16_t getMessageId() const	    { return messageId; }
	uint8_t  getTotalFragments() const  { return totalFragments; }
	uint8_t  getFragmentSequence() const { return fragmentSequence; }
	uint8_t  getReplyType() const	    { return replyType; }

    private:
	string	 message;		// 消息正文，0是分隔符
	uint32_t hasFontAttribute;	// 是否有字体属性，4字节，有一般是0x00000001
	uint16_t messageId;		// 消息id，2字节，同一条消息的不同分片id相同
	uint8_t  totalFragments;	// 消息的分片数，1字节
	uint8_t	 fragmentSequence;	// 分片序号，1字节，从0开始
	uint8_t  replyType;		// 消息类型，这里的类型表示是正常回复
	// 还是自动回复之类的信息， 1字节

};


/**
 * 群消息的信息封装 
 */

class ClusterIMBody {
    public:
	ClusterIMBody(uint16_t source_);
	~ClusterIMBody();
	int getBody(const uint8_t* buf, int len);

	const string& getMessage() const	    { return message; }

	uint32_t getExternalId() const	    { return externalId; }
	uint32_t getClusterId()	 const	    { return clusterId; }
	uint32_t getSender()	 const	    { return sender; }
	uint32_t getSendTime()	 const	    { return sendTime; }
	uint32_t getVersionId()  const	    { return versionId; }
	uint16_t getContentType() const	    { return contentType; }
	uint16_t getImSequence() const	    { return imSequence; }
	uint16_t getClusterSource()const    { return clusterSource; }
	uint16_t getMessageId() const	    { return messageId; }
	uint8_t  getTotalFragments() const  { return totalFragments; }
	uint8_t  getFragmentSequence() const { return fragmentSequence; }
	uint8_t  getClusterType() const	    { return clusterType; }

    private:
	string   message;		// 消息正文，0是分隔符
	// 这个字段在收到临时群消息时表示父群ID，在固定群消息时表示群外部ID
	uint32_t externalId;	
	uint32_t clusterId;	    // 临时群内部ID
	uint32_t sender;	    // 发送者
	uint32_t sendTime;	    // 发送时间
	uint32_t versionId;	    // Member Version ID
	uint16_t contentType;	    // 有没有自定义表情
	uint16_t imSequence;	    // 消息序号
	uint16_t clusterSource;	    // 临时群还是固定群
	uint16_t messageId;	    // 消息id，2字节，同一条消息的不同分片id相同
	uint8_t	 clusterType;	    // 群类型，1字节

	uint8_t  totalFragments;    // 消息的分片数，1字节
	uint8_t	 fragmentSequence;  // 分片序号，1字节，从0开始
};



#endif // _RECEIVE_IM_BODY_H_

